#ifndef UISKIN_H_
#define UISKIN_H_

#include "TextureManager.h"
#include "Texture.h"
#include "ConfigFile.h"
#include "FontManager.h"
#include <string>
#include <gl.h>

#include "Window.h"
#include "UIButton.h"
#include "UILabel.h"

namespace Lame3d
{
	class UISkin
	{
		public:
			UISkin(const File &f, TextureManager &tm, FontManager &fm, const DisplayManager &dM);
			~UISkin();
			
			class Handle
			{
				public:
					~Handle();
					
					const UISkin& Skin() const;
					
					/* The following methods draw with the object's upper-left corner on the gl cursor. */
					void DrawCursor();
					void DrawTextLight(const std::string &text, float width = 1, bool wrap=true);
					void DrawTextDark(const std::string &text, float width = 1, bool wrap=true);
					
					void DrawWindow(const Window &w);
					void DrawLabel(const UILabel &l);
					void DrawButton(const UIButton &b);
					void DrawTextEntry(UITextEntry &e);
					
					Handle& operator=(const Handle &h);
					
				protected:
					Handle(UISkin &sk);
					void bind();
					void unbind();
					
					UISkin *skin;
					
				friend class UISkin;
			};
			
			Handle GetHandle();
			const std::string& Name() const;
			const std::string& Author() const;
			
		protected:
			ConfigFile config;
			TextureManager &textureManager;
			FontManager &fontManager;
			const DisplayManager &displayManager;
			
			int refCount;
			std::string name;
			std::string author;
			
			void load();
			void unload();
			
			void loadFont();
			void loadCursor();
			void loadButton();
			void loadWindowSkin();
			void loadTextBoxSkin();
			
			// Window
			class WindowSkin
			{
				public:
					WindowSkin(Texture &t, float size);
					~WindowSkin();
					
					void Render(const Point2d &dims);
					
				protected:
					Texture::Handle windowTexture;
					
					GLuint upperLeft;
					GLuint upper;
					GLuint upperRight;
					GLuint right;
					GLuint bottomRight;
					GLuint bottom;
					GLuint bottomLeft;
					GLuint left;
					GLuint center;
					
					float size;
					
					void drawRow(GLuint l, GLuint c, GLuint r, int cols, float residue);
					
					GLuint makeList(const Point2d &lowerLeft,
						const Point2d &lowerRight,
						const Point2d &upperRight,
						const Point2d &upperLeft);
			};
			WindowSkin *windowSkin;
			
			// Font
			class FontSkin
			{
				public:
					FontSkin(Font &l, Font &d);
					~FontSkin();
					
					Font::Handle& Light();
					Font::Handle& Dark();
					
				protected:
					Font::Handle light;
					Font::Handle dark;
			};
			FontSkin *fontSkin;
			
			// Cursor
			class CursorSkin
			{
				public:
					CursorSkin(Texture &cursor, float s);
					~CursorSkin();
					
					void Render();
				
				protected:
					Texture::Handle cursor;
					float size;
					GLuint displayList;
			};
			CursorSkin *cursorSkin;
			
			// Button bit
			class ButtonSkin
			{
				public:
					ButtonSkin(Texture &up, Texture &down, float size);
					~ButtonSkin();
					
					void DrawUp(const Point2d &dims);
					void DrawDown(const Point2d &dims);
					
				protected:
					WindowSkin buttonDown;
					WindowSkin buttonUp;
			};
			ButtonSkin *buttonSkin;
			
			// Text box
			class TextBoxSkin
			{
				public:
					TextBoxSkin(Texture &tex, float s);
					~TextBoxSkin();
					
					void Draw(const Point2d &dims);
					
				protected:
					WindowSkin textBoxSkin;
					float size;
			};
			TextBoxSkin *textBoxSkin;
			
		friend class Handle;
	};
}

#endif /*UISKIN_H_*/
